//package com.jpa.demo.persistencecontext;
//
//import org.springframework.beans.BeanUtils;
//import org.springframework.beans.BeansException;
//import org.springframework.beans.PropertyValues;
//import org.springframework.beans.factory.annotation.InjectionMetadata;
//import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
//import org.springframework.core.BridgeMethodResolver;
//import org.springframework.core.annotation.AnnotationUtils;
//import org.springframework.lang.Nullable;
//import org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor;
//import org.springframework.stereotype.Component;
//import org.springframework.util.ClassUtils;
//import org.springframework.util.ReflectionUtils;
//import org.springframework.util.StringUtils;
//
//import javax.persistence.PersistenceContext;
//import javax.persistence.PersistenceUnit;
//import java.beans.PropertyDescriptor;
//import java.lang.reflect.Method;
//import java.lang.reflect.Modifier;
//import java.util.ArrayList;
//import java.util.Arrays;
//import java.util.List;
//import java.util.Map;
//import java.util.concurrent.ConcurrentHashMap;
//
//@Component
//public class MyPersistenceAnnotationBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
//
//    //建立一个注入原数据的缓存数据，key是bean的名称
//    private final transient Map<String, InjectionMetadata> injectionMetadataCache = new ConcurrentHashMap<>(256);
//
//    /**
//     *
//     * @param pvs
//     * @param bean
//     * @param beanName
//     * @return
//     * @throws BeansException
//     */
//    @Override
//    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
//        //获取类中的原数据，其实也就是解析@PersistenceContext注解
//        while(beanName.equals("userService")){
//            InjectionMetadata metadata = findPersistenceMetadata(beanName, bean.getClass(), pvs);
//        }
//        return InstantiationAwareBeanPostProcessor.super.postProcessProperties(pvs, bean, beanName);
//    }
//
//    private InjectionMetadata findPersistenceMetadata(String beanName, final Class<?> clazz, @Nullable PropertyValues pvs) {
//        // Fall back to class name as cache key, for backwards compatibility with custom callers.
//        String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
//        // Quick check on the concurrent map first, with minimal locking.
//        InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
//        if (InjectionMetadata.needsRefresh(metadata, clazz)) {
//            synchronized (this.injectionMetadataCache) {
//                metadata = this.injectionMetadataCache.get(cacheKey);
//                if (InjectionMetadata.needsRefresh(metadata, clazz)) {
//                    if (metadata != null) {
//                        metadata.clear(pvs);
//                    }
//                    metadata = buildPersistenceMetadata(clazz);
//                    this.injectionMetadataCache.put(cacheKey, metadata);
//                }
//            }
//        }
//        return metadata;
//    }
//
//    /**
//     * 也就是将类中的解析元素解析成目标注入类
//     * @param clazz
//     * @return
//     */
//    private InjectionMetadata buildPersistenceMetadata(final Class<?> clazz) {
//        if (!AnnotationUtils.isCandidateClass(clazz, Arrays.asList(PersistenceContext.class, PersistenceUnit.class))) {
//            return InjectionMetadata.EMPTY;
//        }
//
//        List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
//        Class<?> targetClass = clazz;
//
//        do {
//            final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
//
//            ReflectionUtils.doWithLocalFields(targetClass, field -> {
//                if (field.isAnnotationPresent(PersistenceContext.class) ||
//                        field.isAnnotationPresent(PersistenceUnit.class)) {
//                    if (Modifier.isStatic(field.getModifiers())) {
//                        throw new IllegalStateException("Persistence annotations are not supported on static fields");
//                    }
////                    currElements.add(new PersistenceAnnotationBeanPostProcessor.PersistenceElement(field, field, null));
//                }
//            });
//
//            ReflectionUtils.doWithLocalMethods(targetClass, method -> {
//                Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
//                if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
//                    return;
//                }
//                if ((bridgedMethod.isAnnotationPresent(PersistenceContext.class) ||
//                        bridgedMethod.isAnnotationPresent(PersistenceUnit.class)) &&
//                        method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
//                    //不能是静态方法
//                    if (Modifier.isStatic(method.getModifiers())) {
//                        throw new IllegalStateException("Persistence annotations are not supported on static methods");
//                    }
//                    if (method.getParameterCount() != 1) {
//                        throw new IllegalStateException("Persistence annotation requires a single-arg method: " + method);
//                    }
//                    PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
////                    currElements.add(new PersistenceAnnotationBeanPostProcessor.PersistenceElement(method, bridgedMethod, pd));
//                }
//            });
//
//            elements.addAll(0, currElements);
//            targetClass = targetClass.getSuperclass();
//        }
//        while (targetClass != null && targetClass != Object.class);
//
//        return InjectionMetadata.forElements(elements, clazz);
//    }
//
//}
